package com.shxzz.easy12306.services.pay.handler.ali;

import cn.hutool.core.text.CharSequenceUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.shxzz.easy12306.framework.starter.convention.exceptions.ServiceException;
import com.shxzz.easy12306.services.pay.common.enums.PayChannelEnum;
import com.shxzz.easy12306.services.pay.common.enums.PayTradeTypeEnum;
import com.shxzz.easy12306.services.pay.common.enums.TradeStatusEnum;
import com.shxzz.easy12306.services.pay.dto.ali.AliRefundRequest;
import com.shxzz.easy12306.services.pay.dto.base.RefundRequest;
import com.shxzz.easy12306.services.pay.dto.resp.RefundResponse;
import com.shxzz.easy12306.services.pay.handler.base.RefundHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.UUID;


/**
 * @author shxzz
 * @create 2024-03-17-22:55
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class AliRefundHandler implements RefundHandler {

    private final AlipayClient alipayClient;
    private static final String SUCCESS_CODE = "10000";

    private static final String FUND_CHANGE = "Y";


    @Override
    public String mark() {
        return PayChannelEnum.ALI_PAY.name() + "_"
                + PayTradeTypeEnum.NATIVE.name()
                + "_" + TradeStatusEnum.TRADE_CLOSED.getTradeCode();
    }

    @Override
    public RefundResponse executeResp(RefundRequest requestParam) {
        AliRefundRequest aliRefundRequest = (AliRefundRequest) requestParam;
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(aliRefundRequest.getOrderSn());
        model.setTradeNo(aliRefundRequest.getTradeNo());
        BigDecimal refundAmount = aliRefundRequest.getRefundAmount().divide(new BigDecimal(100), RoundingMode.HALF_UP);
        model.setRefundAmount(refundAmount.toString());
        model.setOutRequestNo(UUID.randomUUID().toString().replace("-", ""));
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizModel(model);
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(request);
            log.info("发起支付宝退款，订单号：{}，交易凭证号：{}，退款金额：{}",
                    aliRefundRequest.getOrderSn(),
                    aliRefundRequest.getTradeNo(),
                    refundAmount.intValue()
            );
            if (!CharSequenceUtil.equals(SUCCESS_CODE, response.getCode())
                    || !CharSequenceUtil.equals(FUND_CHANGE, response.getFundChange())) {
                throw new ServiceException("退款失败");
            }
            return new RefundResponse(TradeStatusEnum.TRADE_CLOSED.getTradeCode(), response.getTradeNo());
        } catch (AlipayApiException e) {
            throw new ServiceException("调用支付宝退款异常");
        }
    }
}
